package net.orange.architecture.aop;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;

import net.orange.architecture.audit.ActionInfo;
import net.orange.architecture.audit.IAuditInfo;
import net.orange.architecture.audit.IAuditable;
import net.orange.architecture.audit.IAuditor;
import net.orange.architecture.web.Web;

import org.springframework.aop.MethodBeforeAdvice;

/**
 * The action AOP advice which purpose is write down every user action in
 * system.
 */
public class ActionInterceptor implements MethodBeforeAdvice, IAuditable {

	/**
	 * The observers, it can be log file,database table or others.
	 */
	protected Collection<IAuditor> auditors;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method,
	 *      java.lang.Object[], java.lang.Object)
	 */
	public void before(Method arg0, Object[] arg1, Object arg2)
			throws Throwable {
		notifyAuditor(new ActionInfo(arg0, arg1, arg2, Web.getCurrentUser()));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see net.orange.architecture.audit.IAuditable#addAuditor(net.orange.architecture.audit.IAuditor)
	 */
	public void addAuditor(IAuditor auditor) {
		if (auditors == null)
			auditors = new ArrayList<IAuditor>();
		auditors.add(auditor);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see net.orange.architecture.audit.IAuditable#removeAuditor(net.orange.architecture.audit.IAuditor)
	 */
	public void removeAuditor(IAuditor auditor) {
		if (auditors != null)
			auditors.remove(auditor);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see net.orange.architecture.audit.IAuditable#notifyAuditor(net.orange.architecture.audit.IAuditInfo)
	 */
	public void notifyAuditor(IAuditInfo info) {
		if (auditors != null) {
			for (IAuditor auditor : auditors)
				if (auditor != null)
					auditor.update(info);
		}
	}

	/**
	 * @return Returns the auditors.
	 */
	public Collection<IAuditor> getAuditors() {
		return auditors;
	}

	/**
	 * @param auditors
	 *            The auditors to set.
	 */
	public void setAuditors(Collection<IAuditor> auditors) {
		this.auditors = auditors;
	}
}
